fix(rsc): pre-include React peers in client env optimizeDeps (fix #1213)#1214
Closed
jgeurts wants to merge 2 commits into
Closed
fix(rsc): pre-include React peers in client env optimizeDeps (fix #1213)#1214jgeurts wants to merge 2 commits into
jgeurts wants to merge 2 commits into
Conversation
7977aeb to
91e8832
Compare
The client environment only had `react-dom/client` and the React Server DOM browser entry in `optimizeDeps.include`. React itself and crawled React-peer packages were discovered lazily as the browser requested modules, which re-runs the optimizer mid-load and changes the `?v=` hash on already-served chunks. The browser ends up with two distinct React module records, and `'use client'` libraries that synchronously call hooks in providers hit the wrong dispatcher (`React.H` is null), throwing `Invalid hook call`. Mirror the SSR/RSC env behaviour by including `react`, `react-dom`, `react/jsx-runtime`, `react/jsx-dev-runtime`, plus the React-peer packages from `crawlFrameworkPkgs`. Filter that list to packages whose bare specifier resolves from the user's project root, so server-only React peers (e.g. the `@vitejs/test-dep-client-in-server` fixture, which only exports `./server`) don't break dep optimization.
91e8832 to
2eeb6ac
Compare
Stands up an isolated dev fixture with a `'use client'` third-party package that calls `useMemo` synchronously in a Provider. Without the client env `optimizeDeps.include` fix, lazy discovery on first request changes the React `?v=` hash mid-load, the browser ends up with two React module records, and `Invalid hook call` fires. Watches both `pageerror` and `console` events so React errors that the dev error boundary recovers from still fail the assertion.
Contributor
|
Thanks for the PR. Closing for now. See the rational in #1213 (comment) |
Author
|
Thanks for the quick review and the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix #1213
Summary
The
clientenvironment'soptimizeDeps.includeonly listedreact-dom/clientand one React Server DOM entry — notreact,react/jsx-runtime, or any of the React-peer packages crawled bycrawlFrameworkPkgs. Those got discovered lazily as the browserrequested modules, the optimizer re-ran mid-load, and the
?v=hashchanged on chunks that had already been served. The browser ended up
with two distinct React module records, and
'use client'librariesthat synchronously call hooks in providers hit the wrong dispatcher
(
React.His null), throwingInvalid hook call.The
ssrandrscenvs don't hit this because theiroptimizeDeps.includealready listsreact,react-dom,react/jsx-runtime, andreact/jsx-dev-runtime.Change
Mirror the SSR/RSC env behaviour for the
clientenv: pre-includethose four React subpaths plus the React-peer packages that
crawlFrameworkPkgsalready discovers fornoExternal. Filter thatspread to packages whose bare specifier resolves from the user's
project root — server-only React peers (e.g. the
@vitejs/test-dep-client-in-servertest fixture, which only exports./server) would otherwise break dep optimization.Reproduction
Repro repo: https://github.com/jgeurts/vite-rsc-cjs-subpath-named-exports
The page mounts, then the browser console shows two
Invalid hook callerrors and a
TypeError: Cannot read properties of null (reading 'useMemo')where the React,
@liveblocks_react, andreact-dom_clientchunks eachcarry a different
?v=hash. With this PR applied (drop the patched@vitejs/plugin-rscinto the repro'snode_modules), the page renderscleanly.
Verification
pnpm test).examples/basicruns cleanly inpnpm devandpnpm buildafterthe change. The fixture exercises a wide range of
'use client'/'use server'paths, including the@vitejs/test-dep-client-in-serverfixture that lacks a
.export — confirms the resolution-based filterworks.
e2e/use-client-hook-in-provider.test.tsstandsup an isolated dev fixture with a
'use client'package that callsuseMemosynchronously in a Provider. With the fix it passes; withthe fix reverted it fails the dev case (the build case still passes —
this bug is dev-only).